﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Urs.Data.Domain.Directory;
using Urs.Plugin.Shipping.ByWeight.Domain;
using Urs.Plugin.Shipping.ByWeight.Models;
using Urs.Plugin.Shipping.ByWeight.Services;
using Urs.Services.Configuration;
using Urs.Services.Directory;
using Urs.Services.Localization;
using Urs.Services.Security;
using Urs.Services.Shipping;
using Urs.Framework;
using Urs.Framework.Controllers;
using Urs.Framework.Kendoui;
using Urs.Framework.Mvc;
using Urs.Framework.Mvc.Filters;

namespace Urs.Plugin.Shipping.ByWeight.Controllers
{
    [AdminAuthorize]
    [Area("Admin")]
    public class ShippingByWeightController : BasePluginController
    {
        private readonly IShippingService _shippingService;
        private readonly ShippingByWeightSettings _shippingByWeightSettings;
        private readonly IShippingByWeightService _shippingByWeightService;
        private readonly ISettingService _settingService;
        private readonly ILocalizationService _localizationService;
        private readonly IAreaService _areaService;

        public ShippingByWeightController(IShippingService shippingService,
            ShippingByWeightSettings shippingByWeightSettings,
            IShippingByWeightService shippingByWeightService, ISettingService settingService,
            ILocalizationService localizationService,
            IAreaService areaService)
        {
            this._shippingService = shippingService;
            this._shippingByWeightSettings = shippingByWeightSettings;
            this._shippingByWeightService = shippingByWeightService;
            this._settingService = settingService;
            this._localizationService = localizationService;
            this._areaService = areaService;
        }

        #region Methods

        public ActionResult Configure()
        {
            return View("~/Plugins/Shipping.ByWeight/Views/Configure.cshtml");
        }

        public IActionResult RatesList(PageRequest command)
        {
            var records = _shippingByWeightService.GetAll(command.Page - 1, command.Limit);
            var sbwModel = records.Select(x =>
            {
                var m = new ShippingByWeightModel()
                {
                    Id = x.Id,
                    ShippingMethodId = x.ShippingMethodId,
                    First = x.First,
                    Plus = x.Plus,
                    FirstPrice = x.FirstPrice,
                    PlusPrice = x.PlusPrice
                };

                if (x.Scopes.Count > 0)
                {
                    var areas = new List<string>();
                    var provinceCodes = x.Scopes.Select(s => s.ProvinceCode).Distinct().ToList();

                    foreach (var pCode in provinceCodes)
                    {
                        var province = _areaService.GetProvincesByCode().FirstOrDefault(q => q.Code == pCode);
                        var cities = _areaService.GetCitiesByProvinceCode(province.Code);
                        var count = cities.Count();
                        var scope = x.Scopes.Where(s => s.ProvinceCode == pCode);
                        var scopeCount = scope.Count();
                        if (count != scopeCount)
                            foreach (var s in scope)
                            {
                                var city = cities.FirstOrDefault(c => c.Code == s.CityCode);
                                areas.Add(city.Name);
                            }
                        else
                            areas.Add(province.Name);
                    }
                    m.AreasName = string.Join(",", areas);
                }
                else
                    m.AreasName = _localizationService.GetResource("Plugins.Shipping.ByPiece.Fields.Default");


                var shippingMethod = _shippingService.GetShippingMethodById(x.ShippingMethodId);
                m.ShippingMethodName = (shippingMethod != null) ? shippingMethod.Name : "Unavailable";

                return m;
            }).ToList();
            var model = new ResponseResult
            {
                data = sbwModel,
                count = records.TotalCount
            };

            return Json(model);
        }

        public ActionResult RateDelete(int id)
        {
            var sbw = _shippingByWeightService.GetById(id);
            if (sbw != null)
                _shippingByWeightService.DeleteShippingByWeightRecord(sbw);

            return new NullJsonResult();
        }

        #region item

        //edit
        public ActionResult EditPopup(int? id)
        {
            var model = new ShippingByWeightModel();
            var sbw = new ShippingByWeightRecord();
            if (id.HasValue)
            {
                sbw = _shippingByWeightService.GetById(id.Value);
                model.Id = sbw.Id;
                model.Plus = sbw.Plus;
                model.PlusPrice = sbw.PlusPrice;
                model.ShippingMethodId = sbw.ShippingMethodId;
                model.First = sbw.First;
                model.FirstPrice = sbw.FirstPrice;
            }

            var provinces = _areaService.GetProvincesByCode(); ;

            var provinceCodes = sbw.Scopes.Select(s => s.ProvinceCode).Distinct().ToList();

            foreach (var province in provinces)
            {
                var cities = _areaService.GetCitiesByProvinceCode(province.Code);
                var count = cities.Count();
                var scope = sbw.Scopes.Where(s => s.ProvinceCode == province.Code);
                var scopeCount = scope.Count();
                var selected = false;
                if (count == scopeCount)
                    selected = true;

                var editShipping = new EditShippingScopeModel();
                editShipping.Code = province.Code;
                editShipping.Name = province.Name;
                editShipping.Selected = selected;
                editShipping.Count = scopeCount;

                foreach (var item in cities)
                {
                    var c = sbw.Scopes.FirstOrDefault(x => x.ProvinceCode == province.Code && x.CityCode == item.Code);
                    var cselected = false;
                    if (c != null)
                    {
                        cselected = true;
                        editShipping.Disabled = true;
                    }

                    var city = new EditShippingScopeModel.ShippingCityModel();
                    city.Code = item.Code;
                    city.Name = item.Name;
                    city.Selected = cselected;

                    editShipping.Cities.Add(city);
                }
                model.Scopes.Add(editShipping);
            }

            var shippingMethods = _shippingService.GetAllShippingMethods();
            if (!shippingMethods.Any())
                return Content("No shipping methods can be loaded");

            var selectedShippingMethod = _shippingService.GetShippingMethodById(sbw.ShippingMethodId);
            //shipping methods
            foreach (var sm in shippingMethods)
                model.AvailableShippingMethods.Add(new SelectListItem { Text = sm.Name, Value = sm.Id.ToString(), Selected = (selectedShippingMethod != null && sm.Id == selectedShippingMethod.Id) });

            return View("~/Plugins/Shipping.ByWeight/Views/EditPopup.cshtml", model);
        }

        [HttpPost]
        public ActionResult EditPopup(ShippingByWeightModel model)
        {
            var entity = _shippingByWeightService.GetById(model.Id);
            if (entity == null)
            {
                entity = new ShippingByWeightRecord();
                entity.Plus = model.Plus;
                entity.PlusPrice = model.PlusPrice;
                entity.ShippingMethodId = model.ShippingMethodId;
                entity.First = model.First;
                entity.FirstPrice = model.FirstPrice;
                _shippingByWeightService.InsertShippingByWeightRecord(entity);
            }
            else
            {
                entity.Plus = model.Plus;
                entity.PlusPrice = model.PlusPrice;
                entity.ShippingMethodId = model.ShippingMethodId;
                entity.First = model.First;
                entity.FirstPrice = model.FirstPrice;
                _shippingByWeightService.UpdateShippingByWeightRecord(entity);
            }

            if (model.City != null && model.City.Count() > 0)
            {
                var scopes = _shippingByWeightService.GetScopesByPieceRecordId(entity.Id);
                foreach (var item in scopes)
                    _shippingByWeightService.DeleteShippingScope(item);

                foreach (var cityCode in model.City)
                {
                    var city = _areaService.GetCityByCityCode(cityCode);
                    var sbw = new ShippingScopeByWeightRecord()
                    {
                        ShippingByWeightRecordId = entity.Id,
                        ProvinceCode = city.ProvinceCode,
                        CityCode = city.CityCode
                    };
                    _shippingByWeightService.InsertShippingScope(sbw);
                }
            }

            return Json(new { success = 1 });
        }

        #endregion

        #endregion
    }
}